<template>
  <div>
    <van-nav-bar title="编辑资料" left-arrow @click-left="$router.back()" />

    <div class="avatar-box">
      <van-image
        round
        width="3.5rem"
        height="3.5rem"
        fit="cover"
        :src="userInfo.photo"
      />
      <!-- 选择完图片后调用的回调函数 -->
      <van-uploader :after-read="afterRead" />
    </div>

    <van-cell-group>
      <van-cell
        @click="showNameFn"
        title="名称"
        :value="userInfo.name"
        is-link
      />
      <van-cell
        @click="sexShow = true"
        title="性别"
        :value="userInfo.gender ? '男' : '女'"
        is-link
      />
      <van-cell
        @click="showBirthFn"
        title="生日"
        :value="userInfo.birthday"
        is-link
      />
    </van-cell-group>

    <!-- v-model是用来控制这个弹出框的显示和隐藏 -->
    <van-dialog
      @confirm="saveName"
      v-model="showName"
      title="标题"
      show-cancel-button
    >
      <van-field v-model="inpName" placeholder="请输入用户名" />
    </van-dialog>

    <!-- 性别修改的弹出层 -->
    <van-popup v-model="sexShow" position="bottom" :style="{ height: '18%' }">
      <van-nav-bar
        title="修改性别"
        left-text="取消"
        @click-left="sexShow = false"
      />
      <van-cell-group>
        <van-cell title="男" @click="changeGender(1)" is-link />
        <van-cell title="女" @click="changeGender(0)" is-link />
      </van-cell-group>
    </van-popup>

    <!-- 生日修改的弹出层 -->
    <van-popup v-model="birthShow" position="bottom" :style="{ height: '30%' }">
      <!-- 时间选择器里的v-model是用来对日期做双向绑定 -->
      <van-datetime-picker
        @confirm="changeBirth"
        @cancel="birthShow = false"
        v-model="currentDate"
        type="date"
        title="选择年月日"
        :min-date="minDate"
        :max-date="maxDate"
      />
    </van-popup>

    <!-- 专用来做裁剪的大盒子 -->
    <div v-if="cropShow" class="crop-box">
      <vueCropper
        ref="cropper"
        :img="cropImg"
        autoCrop
        autoCropWidth="160"
        autoCropHeight="160"
      ></vueCropper>

      <van-button @click="doCrop" class="crop-btn crop-btn-ok" type="primary"
        >裁剪</van-button
      >
      <van-button
        @click="cropShow = false"
        class="crop-btn crop-btn-cancel"
        type="primary"
        >取消</van-button
      >
    </div>
  </div>
</template>

<script>
import moment from "moment";
// 组件
import { VueCropper } from "vue-cropper";

export default {
  components: {
    VueCropper,
  },

  data() {
    return {
      cropImg: "",
      // 到时候用户的生日是多少，这里就改成多少
      currentDate: new Date(),
      // 最小能选择的为1949-10-1
      minDate: new Date("1949-10-1"),
      // 最大能选择的日期，就是当天
      // new Date()如果什么都不传，就是获取当前时间
      maxDate: new Date(),
      birthShow: false,
      // 控制显示名字的弹出框
      showName: false,
      inpName: "",
      sexShow: false,
      cropShow: false,
    };
  },
  methods: {
    showNameFn() {
      // 把当前的用户名字传递给输入框
      this.inpName = this.userInfo.name;
      // 显示弹出框
      this.showName = true;
    },

    // 点击名字里的确认按钮点击事件
    async saveName() {
      // 不为空才发请求
      if (this.inpName != "") {
        try {
          // 发请求给服务器
          await this.$axios({
            url: "/v1_0/user/profile",
            method: "patch",
            data: {
              name: this.inpName,
            },
          });

          // 发请求成功后，而是直接把本地的也改了
          this.$store.commit("setUserInfo", {
            ...this.userInfo,
            name: this.inpName,
          });
        } catch {
          this.$toast.fail("修改失败！");
        }
      }
    },

    // 性别的点击事件
    async changeGender(gender) {
      try {
        // 发请求
        await this.$axios({
          url: "/v1_0/user/profile",
          method: "patch",
          data: {
            gender: gender,
          },
        });

        // 修改成功要修改vuex
        this.$store.commit("setUserInfo", {
          ...this.userInfo,
          gender: gender,
        });

        // 把弹出层隐藏
        this.sexShow = false;
      } catch {
        this.$toast.fail("修改失败");
      }
    },

    // 生日的点击事件
    showBirthFn() {
      // 显示之前那把当前生日传递过去
      this.currentDate = new Date(this.userInfo.birthday);
      // 显示日期
      this.birthShow = true;
    },

    // 修改生日的点击事件
    async changeBirth() {
      // YYYY代表年，写四个Y代表占4位
      // MM 代表月：写2个代表占2位 比如1月就变 01
      // DD 代表日：写2个代表占2位
      // moment()如果什么都不传，就是以当前时间来处理字符串
      // 如果传了什么日期，就是以你传的日期来格式化
      // console.log(moment(this.currentDate).format('YYYY-MM-DD'))
      // 要把日期对象转成时间字符串
      // 可以自己转，也可以调用插件帮我们转
      // 发请求
      const birthday = moment(this.currentDate).format("YYYY-MM-DD");
      await this.$axios({
        url: "/v1_0/user/profile",
        method: "patch",
        data: {
          birthday: birthday,
        },
      });

      // 成功后修改vuex
      this.$store.commit("setUserInfo", {
        ...this.userInfo,
        birthday: birthday,
      });

      // 成功后隐藏弹出层
      this.birthShow = false;
    },

    // 选择图片调用
    afterRead(file) {
      // 参数有两个属性
      // content：是你选择的图片的base64编码格式
      // file：是你选择的图片对象
      // console.log(file);

      // 把选择的图片的base64给裁剪区域
      this.cropImg = file.content;
      // 把裁剪区域给显示出来
      this.cropShow = true;
    },

    // 裁剪的点击事件
    doCrop() {
      this.$refs.cropper.getCropBlob(async (data) => {
        // // do something
        // console.log('裁减了', data);
        // 得到了裁剪后的图片，就上传到服务器

        // 在很久很久以前，ajax默认是不支持上传文件的
        // 后面H5里面出了ajax2.0版，可以上传文件了
        // 但是要依赖一个对象，这个对象叫 FormData
        let fm = new FormData()
        // 把要上传的图片添加到FormData里
        fm.append('photo', data) 
        let res = await this.$axios({
          url: '/v1_0/user/photo',
          method: 'patch',
          data: fm
        })
        // 上传成功后，改掉vuex里的数据
        // console.log(res)
        this.$store.commit('setUserInfo', {
          ...this.userInfo,
          photo: res.data.data.photo
        })

        // 隐藏裁剪容器
        this.cropShow = false
      });
    },
  },
  computed: {
    userInfo() {
      return this.$store.state.userInfo;
    },
  },

  async created() {
    // 判断一下vuex里如果没有数据才发请求
    if (!this.userInfo.name) {
      // 发请求
      let res = await this.$axios({
        url: "/v1_0/user/profile",
      });

      // 把数据存到vuex里
      this.$store.commit("setUserInfo", res.data.data);
    }
  },
};
</script>

<style scoped>
.avatar-box {
  height: 150px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.van-field {
  border: 1px solid #ddd;
}

.van-uploader {
  position: absolute;
}

/* 
  vw：视口宽度
  vh: 视口高度
*/
::v-deep .van-uploader__upload {
  width: 100vw !important;
  height: 150px !important;
  margin: 0 !important;
  /* 透明度 */
  opacity: 0;
}

.crop-box {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  background-color: #f00;
}

.crop-btn {
  position: fixed;
  bottom: 0;
}
.crop-btn-ok {
  left: 0;
}

.crop-btn-cancel {
  right: 0;
}
</style>